<html>
<head><meta charset="utf-8"><title>Trying to understand Box&#x27;s design · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html">Trying to understand Box&#x27;s design</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="210977752"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/210977752" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#210977752">(Sep 23 2020 at 09:23)</a>:</h4>
<p>There are a few things in Box that I never quite understood, if anyone wants to give me code examples of why they are necessary i'd love that :)<br>
(I read the nomicon on Drop check and PhantomData a bunch of time, the latter i've used myself a lot in lifetimes contexts)</p>
<ol>
<li>The <code>box</code> keyword, why is that needed?</li>
<li>The <code>owned_box</code> lang item, why is that needed?</li>
<li>The <code>#[may_dangle]</code> attribute on Drop<br>
4 . Why  the <code>PhantomData&lt;T&gt;</code> in <code>Unique</code> is needed</li>
</ol>
<p>Here's a minimal example of a <code>Box</code> impl without all of these that seems to be working, so I'm looking for examples on what doesn't work and which of the 4 questions solve those examples.<br>
<a href="https://play.rust-lang.org/?gist=d308dda3358e13151a32e551661ad58b">https://play.rust-lang.org/?gist=d308dda3358e13151a32e551661ad58b</a></p>
<p>Thanks in advance :)</p>



<a name="210978230"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/210978230" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Laurențiu <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#210978230">(Sep 23 2020 at 09:28)</a>:</h4>
<p><a href="https://manishearth.github.io/blog/2017/01/10/rust-tidbits-box-is-special/">https://manishearth.github.io/blog/2017/01/10/rust-tidbits-box-is-special/</a></p>



<a name="210978309"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/210978309" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Laurențiu <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#210978309">(Sep 23 2020 at 09:29)</a>:</h4>
<p>Specifically,</p>
<blockquote>
<p>You could move out of deref with <code>Box&lt;T&gt;</code></p>
</blockquote>



<a name="210978344"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/210978344" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#210978344">(Sep 23 2020 at 09:29)</a>:</h4>
<p>we also add special attributes for box during codegen (which is why it has to be a lang item)</p>



<a name="210978683"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/210978683" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#210978683">(Sep 23 2020 at 09:32)</a>:</h4>
<p><span class="user-mention silent" data-user-id="203546">Laurențiu Nicola</span> <a href="#narrow/stream/122651-general/topic/Trying.20to.20understand.20Box's.20design/near/210978309">said</a>:</p>
<blockquote>
<p>Specifically,</p>
<blockquote>
<p>You could move out of deref with <code>Box&lt;T&gt;</code></p>
</blockquote>
</blockquote>
<p>Nice! I assume this is done via the lang item <code>owned_box</code>? now 3 more questions to go <span aria-label="wink" class="emoji emoji-1f609" role="img" title="wink">:wink:</span></p>



<a name="210980067"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/210980067" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#210980067">(Sep 23 2020 at 09:46)</a>:</h4>
<p>The <code>box</code> keyword was to guarantee that the value would be directly written to the allocated memory without first going through the stack (placement in). This ended up not working out, but the <code>box</code> keyword was never removed for <code>Box&lt;T&gt;</code>. It used to also allow other types to be constructed, but that is no longer the case.</p>



<a name="210980380"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/210980380" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#210980380">(Sep 23 2020 at 09:49)</a>:</h4>
<blockquote>
<ol start="3">
<li>The #[may_dangle] attribute on Drop</li>
</ol>
</blockquote>
<p>This makes it possible to write code like</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nb">Box</span>::<span class="n">new</span><span class="p">(</span><span class="n">std</span>::<span class="n">cell</span>::<span class="n">RefCell</span>::<span class="n">new</span><span class="p">(</span><span class="nb">None</span><span class="p">)),</span><span class="w"> </span><span class="n">vec</span><span class="o">!</span><span class="p">[</span><span class="mi">0</span><span class="k">u8</span><span class="p">]);</span><span class="w"></span>
<span class="w">    </span><span class="o">*</span><span class="n">a</span><span class="p">.</span><span class="n">borrow_mut</span><span class="p">()</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="o">&amp;</span><span class="n">b</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>

<p><code>a</code> and <code>b</code> don't strictly outlive each other according to dropck. This means that <code>b</code> could be dropped before <code>a</code>. Normally that would make it possible to access a dangling pointer from the <code>Drop</code> impl, but <code>#[may_dangle]</code> says that you will not do so.</p>



<a name="210980747"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/210980747" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#210980747">(Sep 23 2020 at 09:52)</a>:</h4>
<p><span class="user-mention silent" data-user-id="133247">bjorn3</span> <a href="#narrow/stream/122651-general/topic/Trying.20to.20understand.20Box's.20design/near/210980067">said</a>:</p>
<blockquote>
<p>The <code>box</code> keyword was to guarantee that the value would be directly written to the allocated memory without first going through the stack (placement in). This ended up not working out, but the <code>box</code> keyword was never removed for <code>Box&lt;T&gt;</code>. It used to also allow other types to be constructed, but that is no longer the case.</p>
</blockquote>
<p>It would be interesting to understand why it didn't worked out, but as of now it doesn't achieve anything, right?</p>



<a name="210980749"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/210980749" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#210980749">(Sep 23 2020 at 09:52)</a>:</h4>
<blockquote>
<p>4 . Why the PhantomData&lt;T&gt; in Unique is needed</p>
</blockquote>
<p>This is necessary for the right variance. For example <code>&amp;'a T</code> is covariant in <code>'a</code>meaning that it is possible to go from <code>&amp;'a T</code> to <code>&amp;'b T</code> where <code>'a: 'b</code>. <code>fn(&amp;'a T)</code> is contravariant in <code>'a</code> meaning that it is possible to go from <code>fn(&amp;'a T)</code> to <code>fn(&amp;'b T)</code> where <code>'b: 'a</code>. <code>&amp;'_ mut T</code> is invariant in <code>T</code> meaning that it is not possible to change the lifetimes in <code>T</code>. Otherwise it would be possible to store a <code>T</code> that lives shorter than required in <code>&amp;'_ mut T</code>.</p>



<a name="210980991"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/210980991" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#210980991">(Sep 23 2020 at 09:55)</a>:</h4>
<p><span class="user-mention silent" data-user-id="249222">Elichai Turkel</span> <a href="#narrow/stream/122651-general/topic/Trying.20to.20understand.20Box's.20design/near/210980747">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="133247">bjorn3</span> <a href="#narrow/stream/122651-general/topic/Trying.20to.20understand.20Box's.20design/near/210980067">said</a>:</p>
<blockquote>
<p>The <code>box</code> keyword was to guarantee that the value would be directly written to the allocated memory without first going through the stack (placement in). This ended up not working out, but the <code>box</code> keyword was never removed for <code>Box&lt;T&gt;</code>. It used to also allow other types to be constructed, but that is no longer the case.</p>
</blockquote>
<p>It would be interesting to understand why it didn't worked out, but as of now it doesn't achieve anything, right?</p>
</blockquote>
<p><a href="https://github.com/rust-lang/rust/issues/49733">https://github.com/rust-lang/rust/issues/49733</a> is the current tracking issue for <code>box expr</code>. (<code>box pat</code> has a different tracking issue) <a href="https://github.com/rust-lang/rust/pull/48333">https://github.com/rust-lang/rust/pull/48333</a> has some info about why it didn't work out.</p>



<a name="210982269"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/210982269" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#210982269">(Sep 23 2020 at 10:09)</a>:</h4>
<p><span class="user-mention silent" data-user-id="133247">bjorn3</span> <a href="#narrow/stream/122651-general/topic/Trying.20to.20understand.20Box's.20design/near/210980380">said</a>:</p>
<blockquote>
<blockquote>
<ol start="3">
<li>The #[may_dangle] attribute on Drop</li>
</ol>
</blockquote>
<p>This makes it possible to write code like</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nb">Box</span>::<span class="n">new</span><span class="p">(</span><span class="n">std</span>::<span class="n">cell</span>::<span class="n">RefCell</span>::<span class="n">new</span><span class="p">(</span><span class="nb">None</span><span class="p">)),</span><span class="w"> </span><span class="n">vec</span><span class="o">!</span><span class="p">[</span><span class="mi">0</span><span class="k">u8</span><span class="p">]);</span><span class="w"></span>
<span class="w">    </span><span class="o">*</span><span class="n">a</span><span class="p">.</span><span class="n">borrow_mut</span><span class="p">()</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="o">&amp;</span><span class="n">b</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>

<p><code>a</code> and <code>b</code> don't strictly outlive each other according to dropck. This means that <code>b</code> could be dropped before <code>a</code>. Normally that would make it possible to access a dangling pointer from the <code>Drop</code> impl, but <code>#[may_dangle]</code> says that you will not do so.</p>
</blockquote>
<p>Ha, can't dropck know that <code>b</code> should be dropped only after <code>a</code>? or can this problem also arise with <code>b</code> allocated on top of a or something like that?</p>



<a name="210982497"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/210982497" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#210982497">(Sep 23 2020 at 10:11)</a>:</h4>
<p><code>a</code> and <code>b</code> have the same lifetime lexically. The old borrowck also considered them to have exactly the same lifetime.</p>



<a name="210982654"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/210982654" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#210982654">(Sep 23 2020 at 10:12)</a>:</h4>
<p><span class="user-mention silent" data-user-id="133247">bjorn3</span> <a href="#narrow/stream/122651-general/topic/Trying.20to.20understand.20Box's.20design/near/210980749">said</a>:</p>
<blockquote>
<blockquote>
<p>4 . Why the PhantomData&lt;T&gt; in Unique is needed</p>
</blockquote>
<p>This is necessary for the right variance. For example <code>&amp;'a T</code> is covariant in <code>'a</code>meaning that it is possible to go from <code>&amp;'a T</code> to <code>&amp;'b T</code> where <code>'a: 'b</code>. <code>fn(&amp;'a T)</code> is contravariant in <code>'a</code> meaning that it is possible to go from <code>fn(&amp;'a T)</code> to <code>fn(&amp;'b T)</code> where <code>'b: 'a</code>. <code>&amp;'_ mut T</code> is invariant in <code>T</code> meaning that it is not possible to change the lifetimes in <code>T</code>. Otherwise it would be possible to store a <code>T</code> that lives shorter than required in <code>&amp;'_ mut T</code>.</p>
</blockquote>
<p>I keep reading the variance stuff, and I understand them on &amp;mut T and &amp;T, on lifetimes, I don't quite understand on <code>fn(T) -&gt; U</code> and on Box/Cell etc, like what can <code>Box</code> do that <code>MyBox</code> can't and adding <code>PhantomData&lt;T&gt;</code> will solve?</p>
<p>Thank you for the detailed answers :)</p>



<a name="210982931"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/210982931" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#210982931">(Sep 23 2020 at 10:15)</a>:</h4>
<p>The <code>PhantomData&lt;T&gt;</code> is necessary to tell rustc which of the variances (co-, contra-, invariant) it should use for the type parameter.</p>



<a name="210983454"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/210983454" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#210983454">(Sep 23 2020 at 10:20)</a>:</h4>
<p><a href="https://gist.github.com/bjorn3/df27609cd6193a2545c5460027afa0bd">https://gist.github.com/bjorn3/df27609cd6193a2545c5460027afa0bd</a></p>



<a name="210985478"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/210985478" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#210985478">(Sep 23 2020 at 10:45)</a>:</h4>
<p><span class="user-mention silent" data-user-id="133247">bjorn3</span> <a href="#narrow/stream/122651-general/topic/Trying.20to.20understand.20Box's.20design/near/210983454">said</a>:</p>
<blockquote>
<p><a href="https://gist.github.com/bjorn3/df27609cd6193a2545c5460027afa0bd">https://gist.github.com/bjorn3/df27609cd6193a2545c5460027afa0bd</a></p>
</blockquote>
<p>Did you post this here by mistake?</p>



<a name="210986424"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/210986424" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#210986424">(Sep 23 2020 at 11:00)</a>:</h4>
<p>Yeah, should have been in <a class="stream" data-stream-id="247081" href="/#narrow/stream/247081-t-compiler.2Fperformance">#t-compiler/performance</a>.</p>



<a name="211007419"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/211007419" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#211007419">(Sep 23 2020 at 14:03)</a>:</h4>
<blockquote>
<ol start="4">
<li>Why the <code>PhantomData&lt;T&gt;</code> in <code>Unique&lt;T&gt;</code> is needed<br>
I've given a very detailed explanation about that here: <a href="https://users.rust-lang.org/t/phantomdata-and-dropck-confusion/26624/2">https://users.rust-lang.org/t/phantomdata-and-dropck-confusion/26624/2</a></li>
</ol>
</blockquote>



<a name="211008954"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/211008954" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#211008954">(Sep 23 2020 at 14:12)</a>:</h4>
<p>Is there any non-legacy reason why Box uses Unique instead of <code>NonNull</code> + <code>PhantomData</code> + <code>Send</code>/<code>Sync</code> implementations?</p>



<a name="211009526"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Trying%20to%20understand%20Box%27s%20design/near/211009526" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Trying.20to.20understand.20Box&#x27;s.20design.html#211009526">(Sep 23 2020 at 14:16)</a>:</h4>
<p>I don't think so. Even the unstable message for <code>Unique</code> says "use <code>NonNull</code> instead and consider <code>PhantomData&lt;T&gt;</code> (if you also use <code>#[may_dangle]</code>), <code>Send</code>, and/or <code>Sync</code>".</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>